<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../lib/index.js"></script>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        canvas{
            margin: 50px auto 0;
            display: block;
            background: yellow;
        }
        p {
            font-size: 20px;
            text-decoration: underline;
            text-decoration-color: rgba(64, 235, 255, 0.3);
            text-underline-offset: 10px;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script>
    let ctx = document.getElementById('canvas');
    // 获取webgl上下文
    let gl = ctx.getContext('webgl')
    // 顶点着色器
    let VERTEX_SHADER_SOURCE = `
        attribute vec4 aPosition;
        uniform mat4 mat;
        void main(){
            gl_Position = mat * aPosition;
        }
    `;
    // 片元着色器
    const FRAGMENT_SHADER_SOURCE = `
        void main(){
            gl_FragColor = vec4(1.0, 0.0, 0.1, 1.0);
        }
    `;
    let program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
    // 获取 attribute变量，必须在initShader之后
    let aPosition = gl.getAttribLocation(program, 'aPosition')
    // 获取 uniform 变量 mat
    let mat = gl.getUniformLocation(program, 'mat')

    // 创建一组顶点数据   Float32Array类型化数组，用这个数组，既可以知道里面是数据类型
    let points = new Float32Array([
        -0.5,-0.5,  // 10.0
        0.5,-0.5,  // 20.0
        0.0,0.5,  // 30.0
    ])
    // 创建缓冲区
    let buffer = gl.createBuffer();
    // 将缓冲区对象 绑定到 webgl上
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    // 将顶点数据 写入 缓冲区对象
    gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
    // 给顶点赋值 指定给aPosition attribute变量
    gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0 )
    // 激活attribute变量  gl.disableVertexAttribArray(aPosition); 使⽤此⽅法禁⽤
    gl.enableVertexAttribArray(aPosition);

    //
    let eyey = -0.1;
    function animation(){
        eyey += 0.01;
        if(eyey > 1){
            eyey = -0.1
        }

        // 获取外面的视图矩阵
        let vm = getViewMatrix(0.0,eyey,0.2, 0.0,0.0,0.0, 0.0,0.6,0.0);
        // 我们这里使用的是mat4的uniform变量 要给它赋值需要新的api
        // 三个参数 旧的 false 新的
        gl.uniformMatrix4fv(mat, false, vm);
        // 执行绘制 绘制三个顶点
        gl.drawArrays(gl.TRIANGLES, 0, 3);

        requestAnimationFrame(animation);
    }

    animation()


    /*
    // 归一化函数
    function normalized(arr){
        let sum = 0;

        for(let i=0; i<arr.length;i++){
            sum += arr[i] * arr[i]
        }
        // sum的开平方
        const middle = Math.sqrt(sum)
        // 这样就实现了 将数组内的每一个数 都归一化到0-1间内
        for(let i=0; i<arr.length;i++){
            arr[i] = arr[i]/middle;
        }
    }

    // 叉积函数 作用是 获取法向量
    function cross(a, b) {
        return new Float32Array([
            a[1] * b[2] - a[2] * b[1],
            a[2] * b[0] - a[0] * b[2],
            a[0] * b[1] - a[1] * b[0],
        ])
    }

    // 点积函数 获取投影长度
    function dot(a, b) {
        return  a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
    }

    // 向量差
    function minus(a,b) {
        return new Float32Array([
            a[0] - b[0],
            a[1] - b[1],
            a[2] - b[2],
        ])
    }

    // 视图矩阵获取
    function getViewMatrix(eyex, eyey, eyez, lookAtx, lookAty, lookAtz, upx, upy, upz){
        // 视点
        let  eye = new Float32Array([eyex, eyey, eyez])
        // 目标点
        let  lookAt = new Float32Array([lookAtx, lookAty, lookAtz])
        // 上方向
        let  up = new Float32Array([upx, upy, upz])

        // z轴 最好实现， 视点和目标点 确定
        let z = minus(eye, lookAt);

        // 在使用这些数据之前 需要先归一化
        normalized(z);
        normalized(up);

        // 然后确定x轴， 因为x轴是同时 垂直于z轴和上方向的
        let x = cross(z, up); // 通过叉积函数

        // 确定Y轴
        let y = cross(x, z);

        // 视图矩阵 4*4 的矩阵 所以 要补齐后面
        return new Float32Array([
            x[0],           y[0],           z[0],           0,
            x[1],           y[1],           z[1],           0,
            x[2],           y[2],           z[2],           0,
            -dot(x,eye),    -dot(y,eye),    -dot(z,eye),    1,
        ])
    }
    */
</script>
</html>
